package com.ctgu.tengyun.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.ctgu.tengyun.exception.TengyunRuntimeException;
import com.ctgu.tengyun.util.StringUtils;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by liaoweizhi on 2019/7/17.
 */
public abstract class MybatisDataSourceConfigHelper {

    private static final Logger logger = LoggerFactory.getLogger(MybatisDataSourceConfigHelper.class);

    private static String validation_query = "SELECT 1 FROM DUAL";

    private static final List<Filter> DRUID_LOG_FILTERS = new ArrayList<>(1);

    public static DataSourceTransactionManager getTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager txManager = new DataSourceTransactionManager();
        txManager.setDataSource(dataSource);
        return txManager;
    }

    public static SqlSessionFactory getSqlSessionFactoryData(List<String> xmlPaths, String configPath, DataSource dataSource) {
        try {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

            List<Resource> resources = new ArrayList<>();
            for (String xmlPath : xmlPaths) {
                Resource[] t = new PathMatchingResourcePatternResolver().getResources(xmlPath);
                resources.addAll(Arrays.asList(t));
            }
            if (!resources.isEmpty()) {
                bean.setMapperLocations(resources.toArray(new Resource[resources.size()]));
            }
            if (!StringUtils.isEmpty(configPath)) {
                bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource(configPath));
            }
            bean.setDataSource(dataSource);
            return bean.getObject();
        } catch (Exception e) {
            logger.error("failed to create data sql session", e);
            throw new TengyunRuntimeException("failed to create data sql session", e);
        }
    }

    public static DataSource createDataSource(String url, String username, String password) {
        return createDataSource(url, username, password, 3, 30);
    }

    public static DataSource createDataSource(String url, String username, String password, int minIdle, int maxActive) {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setMaxIdle(maxActive);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setRemoveAbandoned(true);
        dataSource.setRemoveAbandonedTimeout(280);
        dataSource.setMaxWait(30000);
        dataSource.setValidationQuery(validation_query);
        dataSource.setTestOnBorrow(true);
        return dataSource;
    }

    public static DataSource createDruidDataSource(String url, String username, String password) {
        return createDruidDataSource(url, username, password, 3, 30, null, 30000l);
    }

    public static DataSource createDruidDataSource(String url, String username, String password, Integer samplingRate) {
        return createDruidDataSource(url, username, password, 3, 30, samplingRate, 30000l);
    }

    public static DataSource createDruidDataSource(String url, String username, String password, Long maxWait) {
        return createDruidDataSource(url, username, password, 3, 30, null, maxWait);
    }

    public static DataSource createDruidDataSource(String url, String username, String password, int minIdle, int maxActive, Integer samplingRate, Long maxWait) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setInitialSize(minIdle);
        dataSource.setRemoveAbandoned(true);
        dataSource.setRemoveAbandonedTimeout(280);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        dataSource.setMinEvictableIdleTimeMillis(300000);
        dataSource.setValidationQuery(validation_query);
        dataSource.setTestOnBorrow(true);

        return dataSource;
    }

}
